import random
import logging
from datetime import datetime
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from pymysql import MySQLError
from users.user_utils import create_token, check_token, pwd_isvalid
from users.user_utils import has_token, check_method
from utils.site_tools import md5_hex, send_mail
from .models import UserProfile, Feedback, UserToken
from .forms import UserRegForm, FeedbackForm
from .serializers import UserSerializer
from django.core.validators import validate_email
from django.core.exceptions import ValidationError
from BasketballCommunity.settings import TOKEN_EXPIRE


@csrf_exempt
def register(request):
    code = 0
    msg = 'ok'
    data = 0
    if request.method == 'POST':
        verify_code = True
        if verify_code:
            email = request.POST.get('email', None)
            password = request.POST.get('password', None)
            user_reg_form = UserRegForm()
            user_reg_form.email = email
            user_reg_form.password = password
            if user_reg_form.is_valid():
                try:
                    user_reg_form.save()
                    data = 1
                except MySQLError as e:
                    logging.error(e)
                    code = 30000
                    msg = "服务器出了点小差错"
            else:
                code = 10000
                msg = user_reg_form.errors
        else:
            code = 20000
            msg = "验证码错误"
    else:
        code = 40000
        msg = "请求方法错误"
    return JsonResponse({
        'code': code,
        'msg': msg,
        'data': data
    })


@csrf_exempt
def login(request):
    code = 0
    msg = 'ok'
    data = 0
    if request.method == 'POST':
        email = request.POST.get('email', None)
        password = request.POST.get('password', None)
        if email and password:
            user = UserProfile.objects.filter(email=email).first()
            if user and user.password == md5_hex(password):
                token = create_token(user)
                if token:
                    data = {"token": token}
                else:
                    code = 30000
                    msg = "服务器出了点小差错"
            else:
                code = 10000
                msg = "账号或密码错误"
        else:
            code = 10000
            msg = "账号和密码都是必填的"
    else:
        code = 10000
        msg = "请求方法错误"
    return JsonResponse({
        'code': code,
        'msg': msg,
        'data': data
    })


def get_user_info(request):
    code = 0
    msg = 'ok'
    data = 0
    if request.method == 'GET':
        token = request.GET.get('token', None)
        user = check_token(token)
        if user:
            data = UserSerializer(user, many=False).data
        else:
            code = 10000
            msg = "无效的令牌"
    else:
        code = 10000
        msg = "请求方法错误"
    return JsonResponse({
        'code': code,
        'msg': msg,
        'data': data
    })


@csrf_exempt
def feedback(request):
    code = 0
    msg = 'ok'
    data = 0
    if request.method == 'POST':
        token = request.POST.get('token', None)
        user = check_token(token)
        if user:
            title = request.POST.get('title', None)
            content = request.POST.get('content', None)
            feedback_form = FeedbackForm()
            feedback_form.title = title
            feedback_form.content = content
            if feedback_form.is_valid():
                try:
                    fb = Feedback(user=user, title=title, content=content)
                    fb.save()
                    data = 1
                except MySQLError as e:
                    logging.error(e)
                    code = 30000
                    msg = "服务器出了点小差错"
            else:
                code = 10000
                msg = feedback_form.errors
        else:
            code = 10000
            msg = "无效的令牌"
    else:
        code = 10000
        msg = "请求方法错误"
    return JsonResponse({
        'code': code,
        'msg': msg,
        'data': data})


@csrf_exempt
@check_method('POST')
@has_token
def change_password(request):
    """修改密码"""

    data = {'code': 10000,
            'msg': '密码不能为空,且新密码密码需8到16位,至少包括三项（[a-z],[A-Z],[0-9]和[()~!@#$%^&*-+=_|{}[]:;,.?/]的特殊符号）',
            'data': 0}

    pwd = request.POST.get('password', None)
    new_pwd = request.POST.get('new_password', None)

    if pwd and pwd_isvalid(new_pwd):
        data['msg'] = '无效的令牌'
        token = UserToken.objects.filter(token=request.POST.get('token', None)).first()
        usr = check_token(token)
        if usr:
            data['msg'] = '密码错误'
            if usr.password == md5_hex(pwd):
                usr.password = md5_hex(new_pwd)
                usr.save(update_fields=['password'])
                data = {'code': 0, 'msg': '密码修改成功', 'data': 1}

    return JsonResponse(data)


@csrf_exempt
@check_method('POST')
def verify_code(request):
    """向用户邮箱发送验证码"""

    data = {'code': 10000, 'msg': '邮箱不能为空', 'data': 0}
    email = request.POST.get('email', None)
    try:
        validate_email(email)
    except ValidationError:
        data['msg'] = '邮箱输入错误'
        return JsonResponse(data)

    code = ''.join(random.choices('0123456789', k=6))
    is_send = send_mail(email, code)
    if not is_send:
        data['msg'] = '验证码发送失败'
    else:
        data = {'code': 0, 'msg': '邮箱发送成功', 'data': 1}
    return JsonResponse(data)


@csrf_exempt
@check_method('POST')
@has_token
def logout(request):
    """用户退出登录"""

    token = UserToken.objects.filter(token=request.POST.get('token', None)).first()
    if token and token.add_time > (datetime.now() - TOKEN_EXPIRE):
        token.delete()
        return JsonResponse({'code': 0, 'msg': '用户退出成功', 'data': 1})
    return JsonResponse({'code': 10000, 'msg': '令牌无效', 'data': 0})


@csrf_exempt
@check_method('POST')
@has_token
def tobe_author(request):
    """普通用户成为作者"""

    token = request.POST.get('token', None)
    usr = UserToken.objects.filter(token=token).first()
    if usr:
        usr.type = 1
        usr.save(update_fields=['tyope'])
        return JsonResponse(data={'code': 0, 'msg': '用户退出成功', 'data': 1})
    return JsonResponse({'code': 10000, 'msg': '令牌无效', 'data': 0})


@csrf_exempt
@has_token
def update_info(request):
    """用户获取和更新信息"""

    if request.method == 'GET':
        token = request.GET.get('token', None)
        usr_token = UserToken.objects.filter(token=token).first()
        if usr_token and usr_token.add_time > (datetime.now() - TOKEN_EXPIRE):
            usr = usr_token.user
            data = {'name': usr.name, 'gender': usr.gender,
                    'age': usr.age, 'photo': usr.photo}
            return JsonResponse({'code': 0, 'msg': 'ok', 'data': data})
        else:
            return JsonResponse({'code': 10000, 'msg': '令牌无效', 'data': 0})
    else:
        token = request.POST.get('token', None)
        name = request.POST.get('name', None)
        age = request.POST.get('age', None)
        gender = request.POST.get('gender', None)
        photo = request.POST.get('photo', None)
        if token and name and age and gender and photo:
            usr = check_token(token)
            if usr:
                usr.name = name
                usr.age = age
                usr.gender = gender
                usr.photo = photo
                usr.save()
                return JsonResponse({'code': 0, 'msg': '信息更新成功', 'data': 1})
            else:
                return JsonResponse({'code': 10000, 'msg': '令牌无效', 'data': 0})
        else:
            return JsonResponse({'code': 10000, 'msg': '信息不能为空', 'data': 0})
